"""
Author: Karsten Mueller

TO DO:
See: http://code.google.com/p/processgpr/issues/list
"""

# Standard library imports
import sys, os, ConfigParser

# Major library imports
from numpy import zeros, exp, array

# Enthought library imports
from enthought.chaco.api import  ArrayPlotData, ColorBar, \
                                 CMapImagePlot, \
                                 DataRange1D, DataRange2D, \
                                 LinearMapper, GridMapper, GridDataSource, \
                                 HPlotContainer, ImageData, \
                                 OverlayPlotContainer, Plot, PlotAxis
from enthought.chaco.default_colormaps import *
from enthought.chaco.grid import PlotGrid

from enthought.chaco.tools.api import LineInspector, PanTool, SimpleZoom, SaveTool

from enthought.traits.api import Callable, Enum, Float, HasTraits, \
                                 Button, Instance, Str, Trait, on_trait_change
from enthought.traits.ui.api import Group, Handler, HGroup, VGroup, Item, View
from enthought.traits.ui.menu import Action, CloseAction, Menu, \
                                     MenuBar, NoButtons, ToolBar
from enthought.enable.component_editor import ComponentEditor
#from enthought.enable.base_tool import KeySpec  
from enthought.pyface.api import ProgressDialog
                                  
# Own library imports
from processGPR import HUBRA                              
from gprViewerTools import PickTool, PickToolOverlay, TraceSelectTool, \
                           StartViewerTool, StartProcessingTool, ShiftSaveTool, \
                           decay_map



class PlotUI(HasTraits):
    HomeDir = os.getcwd()
    ConfigFile = os.path.join(HomeDir,"resources/default.cfg")
    config = ConfigParser.SafeConfigParser()
    config.read(ConfigFile)
    
    #Traits view definitions:
    traits_view = View(
                       Item('container', editor=ComponentEditor(size=(1200, 800)),
                       show_label=False),
                       buttons=NoButtons,
                       resizable=True)
    
    plot_edit_view = View(Group(Item('min_z', style="simple"),
              Item('max_z', style="simple"),
              Item('colormap'),
              Item('interpolation'),
              Item('ylabel', label="Y-Axis"),
              HGroup(Item('set_as_default', show_label=False),
                     Item('apply_changes', show_label=False))),
              buttons=["OK", "Cancel"],
              x=0.05, y=0.05)


    min_z = Float(config.getfloat('plot settings', 'colorbar_min'))
    max_z = Float(config.getfloat('plot settings', 'colorbar_max'))
    colormap = Enum(color_map_name_dict.keys())
    interpolation = Enum('nearest', 'bilinear', 'bicubic')
    ylabel = Enum(["Depth", "Time", "Elevation"])
    apply_changes = Button()
    set_as_default = Button()#label="Set as default")

    #---------------------------------------------------------------------------
    # Private Traits
    #---------------------------------------------------------------------------
    
    _image_index = Instance(GridDataSource)
    _image_value = Instance(ImageData)

    _cmap = Trait(Blues, Callable)
#    _cmap = Trait(decay_map, Callable)

    #---------------------------------------------------------------------------
    # Public View interface
    #---------------------------------------------------------------------------

    def __init__(self, *args, **kwargs):
        super(PlotUI, self).__init__(*args, **kwargs)
        self.create_plot()
#        self.track_plot()
        
    def create_plot(self):       

        # Create the mapper, etc
        self._image_index = GridDataSource(array([]),
                                          array([]),
                                          sort_order=("ascending", "ascending"))
        image_index_range = DataRange2D(self._image_index)
        self._image_index.on_trait_change(self._metadata_changed,
                                          "metadata_changed")
        
        self._image_value = ImageData(data=array([]), value_depth=1)
        image_value_range = DataRange1D(self._image_value)

        self._image_axes = GridDataSource(array([]),
                                          array([]),
                                          sort_order=("ascending", "ascending"))
        image_axes_range = DataRange2D(self._image_axes)
        self._image_axes.on_trait_change(self._metadata_changed,
                                          "metadata_changed")
        self._axes_mapper=GridMapper(range=image_axes_range)

        # Create the image plot
        self.cmapplot = CMapImagePlot(index=self._image_index, \
                                        value=self._image_value, \
                                        index_mapper=GridMapper(range=image_index_range),
                                        color_mapper=self._cmap(image_value_range), \
                                        origin="top left", \
                                        interpolation=self.interpolation, \
                                        border_visible=True, border_color='black', \
                                        padding=20)
        
        # Add a time axis to the plot
        self.yAxis = PlotAxis(orientation='left',
                        title="Time [ns]",
                        mapper=self.cmapplot.index_mapper._ymapper,
                        component=self.cmapplot)
        self.cmapplot.overlays.append(self.yAxis)
        
    
        # Add a trace axis to the plot
        self.xAxis = PlotAxis(orientation='bottom',
                          title="Trace #",
                          mapper=self.cmapplot.index_mapper._xmapper,
                          component=self.cmapplot)
        self.cmapplot.overlays.append(self.xAxis)
        

        #=======================================================================
        # Add some tools to the plot
        #=======================================================================
        self.cmapplot.tools.append(PanTool(self.cmapplot, drag_button="right",
                                           constrain_key="shift"))
        
        self.zoomtool = SimpleZoom(component=self.cmapplot, tool_mode="box", 
                                   always_on=False)
        self.cmapplot.overlays.append(self.zoomtool)
        
        self.traceselecttool = TraceSelectTool(component=self.cmapplot)
        self.traceselecttool.on_trait_change(self.remove_traces, "confirmed")
        self.cmapplot.overlays.append(self.traceselecttool)
        
        self.picktool = PickTool(component=self.cmapplot)
        self.cmapplot.tools.append(self.picktool)
        self.cmapplot.overlays.append(PickToolOverlay(component=self.cmapplot,
                                               image_inspector=self.picktool))
        self.picktool.on_trait_change(self.update_pick, 'triggered')
        
        self.cmapplot.tools.append(ShiftSaveTool(self.cmapplot, always_on=True, filename="profile_raw.png"))

        self.cmapplot.overlays.append(LineInspector(component=self.cmapplot,
                                               axis='index_x',
                                               inspect_mode="indexed",
                                               write_metadata=True,
                                               is_listener=False,
                                               color="red"))
        self.cmapplot.overlays.append(LineInspector(component=self.cmapplot,
                                               axis='index_y',
                                               inspect_mode="indexed",
                                               write_metadata=True,
                                               color="red",
                                               is_listener=False))
    
        
        # Create a colorbar
        cbar_index_mapper = LinearMapper(range=image_value_range)
        self.colorbar = ColorBar(index_mapper=cbar_index_mapper,
                                 plot=self.cmapplot,
                                 padding_top=self.cmapplot.padding_top,
                                 padding_bottom=self.cmapplot.padding_bottom,
                                 padding_right=50, padding_left=50,
                                 resizable='v',
                                 width=30)
#        self.bartitle = PlotLabel("Backscatter coefficient [dB/m]", component=self.colorbar,
#                                   font = "swiss 12", overlay_position="left",
#                                   angle=90.0, padding_right=50)
#        self.colorbar.overlays.append(self.bartitle)
        # create a range selection for the colorbar
#        range_selection = RangeSelection(component=self.colorbar)
#        self.colorbar.tools.append(range_selection)
#        self.colorbar.overlays.append(RangeSelectionOverlay(component=self.colorbar,
#                                                       border_color="white",
#                                                       alpha=0.8,
#                                                       fill_color="lightgray"))
#    
#        # we also want to the range selection to inform the cmap plot of
#        # the selection, so set that up as well
#        range_selection.listeners.append(self.cmapplot)

        self.pd = ArrayPlotData(line_index=array([]),
                                line_value=array([]),
                                scatter_index=array([]),
                                scatter_value=array([]),
                                scatter_color=array([]))

        self.trace_plot = Plot(self.pd, width=140, orientation="v", resizable="v",
                               default_origin="top left",
                               padding_top=self.cmapplot.padding_top,
                               padding_bottom=self.cmapplot.padding_bottom,
                               padding_left=20,
                               title="Trace #")
        self.trace_plot.plot(("line_index", "line_value"),
                             line_style="solid")
        self.trace_plot.plot(("scatter_index", "scatter_value", "scatter_color"),
                             type="cmap_scatter",
                             name="dot",
                             color_mapper=self._cmap(image_value_range),
                             marker="circle",
                             marker_size=8)
        self.trace_plot.index_range = self.cmapplot.index_range.y_range
        self.trace_plot.y_axis.orientation = "right"
        
        
        # Overlay plot that shows the picked data points from PickTool
        self.pickdata = ArrayPlotData(twt=array([]),
                                trace=array([]),
                                refy=array([]), # contains the reference surface y values
                                refx=array([]), # contains the reference surface x values
                                sky=array([]), # contains the skin depth y values
                                skx=array([])) # contains the traces that have skin depth values

        self.pick_plot = Plot(self.pickdata, padding=self.cmapplot.padding)
        self.pick_plot.plot(("trace", "twt"),
                             type="scatter", name="pick", origin="top left",
                             marker="cross", marker_size=8)
        self.pick_plot.plot(("refx", "refy"),
                             type="scatter", name="refdepth", origin="top left",
                             marker="dot", marker_size=2, color='green')
        self.pick_plot.plot(("skx", "sky"),
                             type="scatter", name="skindepth", origin="top left",
                             marker="dot", marker_size=2, color='red')
        self.pick_plot.value_range = self.cmapplot.index_range.y_range
        self.pick_plot.index_range = self.cmapplot.index_range.x_range
        self.pick_plot.x_axis.visible = False
        self.pick_plot.y_axis.visible = False
        
        # Create containers and add components
        self.overlay_container = OverlayPlotContainer(use_backbuffer=True, 
                                                 unified_draw=True)
        self.overlay_container.add(self.cmapplot)
        self.overlay_container.add(self.pick_plot)
        
        self.container = HPlotContainer(padding=40, fill_padding=True,
                                        bgcolor="white", use_backbuffer=False)
        self.container.add(self.colorbar)
        self.container.add(self.overlay_container)
        self.container.add(self.trace_plot)
        self.container.tools.append(SaveTool(self.container, always_on=True, filename="profile.png"))
    

    def update(self, gpr):
        self.gpr = gpr
        self.colorbar.index_mapper.range.low = self.min_z
        self.colorbar.index_mapper.range.high = self.max_z
        self._image_value.data = self.gpr.data
        self.ylabel = self.gpr.ylabel
        self.container.invalidate_draw()
        self.container.request_redraw()
 
 
    def update_pick(self):
        self.pickdata.set_data("twt", array(self.picktool.picks.twt))
        self.pickdata.set_data("trace", array(self.picktool.picks.trace))

        
    def remove_traces(self):
        ''' Is called when the TraceSelectTool selects a region ...'''
        self.gpr.removeTraces(self.traceselecttool.remove_list[-1])
        self.update(self.gpr)
        self._ylabel_changed()
        
    #---------------------------------------------------------------------------
    # Event handlers
    #---------------------------------------------------------------------------

    def _metadata_changed(self, old, new):
        """ This function takes out a cross section from the image data, based
        on the line inspector selections, and updates the line and scatter 
        plots."""
        
        self.trace_plot.value_range.low = self.min_z 
        self.trace_plot.value_range.high = self.max_z
        if self._image_index.metadata.has_key("selections"):
            x_ndx, y_ndx = self._image_index.metadata["selections"]
            if y_ndx is not None and x_ndx is not None:
                self.trace_plot.title = ('Trace # %i' % self.gpr.tracendx[x_ndx])
                self.pd.set_data("line_value",
                                 self._image_value.data[:, x_ndx])
                xdata, ydata = self._image_index.get_data()
                xdata, ydata = xdata.get_data(), ydata.get_data()
                self.pd.set_data("scatter_index", array([ydata[y_ndx]]))
                self.pd.set_data("scatter_value",
                                 array([self._image_value.data[y_ndx, x_ndx]]))
                self.pd.set_data("scatter_color",
                                 array([self._image_value.data[y_ndx, x_ndx]]))
                try:
                    self.tp.plotdata.set_data("pointx", array([self.gpr.coords.x[x_ndx]]))
                    self.tp.plotdata.set_data("pointy", array([self.gpr.coords.y[x_ndx]]))
                except AttributeError:
                    pass
        else:
            pass
            # Uncommenting the two following lines emptys the trace_plot on mouse exit!
            # self.pd.set_data("scatter_value", array([]))
            # self.pd.set_data("line_value", array([]))
    
    
    #===========================================================================
    # Trait notifications for edit plot
    #===========================================================================
    def _colormap_changed(self):
        self._cmap = color_map_name_dict[self.colormap]
        if hasattr(self, "cmapplot"):
            value_range = self.cmapplot.color_mapper.range
            self.cmapplot.color_mapper = self._cmap(value_range)
            self.trace_plot.plots["dot"][0].color_mapper = self._cmap(value_range)

    def _min_z_changed(self):
        self.colorbar.index_mapper.range.low = self.min_z
        
    def _max_z_changed(self):
        self.colorbar.index_mapper.range.high = self.max_z
        
    def _interpolation_changed(self):
        self.cmapplot.interpolation = self.interpolation 
        
    def _ylabel_changed(self):
        ''' Switch y-axis between time and range '''
        if self.ylabel == "Time":
            self.cmapplot.origin="top left"
            self.trace_plot.default_origin="top left"
            self._image_index.set_data(self.gpr.tracendx, self.gpr.t)
            self.pd.set_data("line_index", self._image_index.get_data()[1]._data)
            self.yAxis.title = "Time [ns]"
        elif self.ylabel == "Depth":
            self.cmapplot.origin="top left"
            self.trace_plot.default_origin="top left"
            self._image_index.set_data(self.gpr.tracendx, self.gpr.r[:,0])
            self.pd.set_data("line_index", self._image_index.get_data()[1]._data)
            self.yAxis.title = "Depth [m]"
        elif self.ylabel == "Elevation":
            self.cmapplot.origin="bottom left"
            self.trace_plot.default_origin="bottom left"
            self._image_index.set_data(self.gpr.tracendx, self.gpr.e)
            self.pd.set_data("line_index", self._image_index.get_data()[1]._data)
            self.yAxis.title = "Elevation [m]"
        
    def _apply_changes_fired(self):
        self.container.request_redraw()
        
    def _set_as_default_fired(self):
        self.config.set('plot settings', 'colorbar_max', str(self.max_z))
        self.config.set('plot settings', 'colorbar_min', str(self.min_z))
        self.config.write(open(self.ConfigFile, 'wb'))

        

class Controller(Handler):

    #---------------------------------------------------------------------------
    # State traits
    #---------------------------------------------------------------------------

    gpr = Instance(HUBRA)
    view = Instance(PlotUI)

    #---------------------------------------------------------------------------
    # Handler interface
    #---------------------------------------------------------------------------

    def init(self, info):
        self.view = info.object.view

    #---------------------------------------------------------------------------
    # Public Controller interface
    #---------------------------------------------------------------------------
    
    ### File Menu
    def new_file(self, ui_info):
        pass
    
    def open_file(self, ui_info):
        st = StartViewerTool(ui_info.ui.context["object"].file, os.getcwd())
        st.edit_traits(kind='modal')
        os.chdir(st.dir)
        
        gpr = HUBRA()
        gpr.readH5(st.file, st.trace_min, st.trace_max, st.sample_min, st.sample_max)
        spt = StartProcessingTool()
        spt.edit_traits(kind='modal')
        
        if spt.stack:
            gpr.stackTraces(spt.stack_no)
        if spt.remove_gating:
            gpr.removeGating()
        if spt.linear_gain:
            gpr.linearGain(spt.lin_gain_val)
        if spt.compensate_spreading:
    #        gpr.compensateSpread(a=0.0)
    #        gpr.compensateVolSpreadDavis()
            gpr.compensateVivaldi()
        if spt.normalize:
            gpr.normalize()
        if spt.decibel:
            gpr.lin2dB()
        if spt.correct_topography:
            gpr.correctTopography()
        
        self.view.gpr = gpr
        self.view.update(self.view.gpr) 
        if gpr.hascoords:
            ui_info.ui.context["object"].statustxt = "File: %s, Total Distance: %8.2f m" % (st.file, gpr.coords.total_distance)
        else:
            ui_info.ui.context["object"].statustxt = "File: %s, Total Distance: N/A" % (st.file)
        ui_info.ui.context["object"].file = st.file
#        view = PlotUI()
#        profileview = ProfileView(gpr=gpr, view=view, statustxt="File: %s, Total Distance: %8.2f m" % (st.file, gpr.coords.total_distance))
#        profileview.configure_traits()

    ### Edit Menu
    def edit_plot(self, ui_info):
        self.view.configure_traits(view="plot_edit_view")
        
    ### View Menu
    def show_trackplot(self, ui_info):
        from gprViewerTools import TrackPlot
        self.view.tp = TrackPlot(self.view.gpr.coords.x, self.view.gpr.coords.y, self.view.gpr.coords.elev)
        self.view.tp.edit_traits()
        
    def show_traceplot(self, ui_info):
        from gprViewerTools import TracePlot
        ndx = int(self.view.trace_plot.title.split(" ")[2]) - self.view.gpr.tracendx[0]
        title = "%s\nx: %.2f, y: %.2f" % (self.view.trace_plot.title,
                                          self.view.gpr.coords.x[ndx],
                                          self.view.gpr.coords.y[ndx])
        tp = TracePlot(self.view.gpr.t, self.view.trace_plot.data.get_data("line_value"),
                       title)
        tp.edit_traits()
        
    def show_decayplot(self, ui_info):
        from gprViewerTools import DecayPlot
        ndx = int(self.view.trace_plot.title.split(" ")[2]) - self.view.gpr.tracendx[0]
        title = "%s\nx: %.2f, y: %.2f" % (self.view.trace_plot.title,
                                          self.view.gpr.coords.x[ndx],
                                          self.view.gpr.coords.y[ndx])
        dp = DecayPlot(self.view.gpr.t, self.view.trace_plot.data.get_data("line_value"),
                       self.view.gpr.cmed, title)
        dp.edit_traits()
        
        
    def show_reflectivityplot(self, ui_info):
        from gprViewerTools import ReflectivityPlot
        R = []
        T = []
        for t in range(self.view.gpr.traces):
            for n in range(self.view.gpr.samples):
                R.append(self.view.gpr.data[n,t])
                T.append(self.view.gpr.t[n])              
        rp = ReflectivityPlot(T, R)
        rp.edit_traits()
        
    def show_metadata(self, ui_info):
        pass
    
    def show_skindepth(self, ui_info):
        if ui_info.ui.context["object"].skindepth_show:
            self.view.pickdata.set_data("sky", array([]))
            self.view.pickdata.set_data("skx", array([]))
            ui_info.ui.context["object"].skindepth_show = not ui_info.ui.context["object"].skindepth_show
        else:
            from scipy.optimize import leastsq
            from numpy import poly1d, sum, cumsum, savez
            traces = self.view.gpr.traces
            x = self.view.gpr.r[:,0]

            pd = zeros((traces,))
            k0 = zeros((traces,))
            A = zeros((traces,))
            
            progress = ProgressDialog(title="Processing %i traces" % traces,
                                      max=traces, show_time=False, can_cancel=False)
            progress.open()
            
            for n in range(traces):
                (cont, skip) = progress.update(n)
                y = 10**(self.view.gpr.data[:,n]/10.0)
                total_power = sum(y)
                z_power = cumsum(y)
                extinction = (total_power-z_power)/total_power
                
                fitfunc = lambda p: exp(-2*p[0]*x-p[1]*x**2) # Target function
                errfunc = lambda p: fitfunc(p) - extinction # Distance to the target function
                p = [0.2, 0.2] # Initial guess for the parameter
                param, success = leastsq(errfunc, p)
                k0[n] = param[0]
                A[n] = param[1]
                pn = poly1d([param[1]*0.5,
                                 param[0],
                                 -1])
                [root1, root2] = pn.r
                if root1>0.0 and root2>0:
                    if root1>root2:
                        pd[n] = root2
                    else:
                        pd[n] = root1
                else:
                    if root1>root2:
                        pd[n] = root1
                    else:
                        pd[n] = root2
#                cc = corrcoef(self.y, fitfunc(param))[0,1]
            progress.update(traces)
            savez("penetration_depth", trace=self.view.gpr.tracendx, pd=pd, k0=k0, A=A,
                  x=self.view.gpr.coords.x, y=self.view.gpr.coords.y, z=self.view.gpr.coords.elev)
            self.view.pickdata.set_data("sky", pd)
            self.view.pickdata.set_data("skx", self.view.gpr.tracendx)           
            ui_info.ui.context["object"].skindepth_show = not ui_info.ui.context["object"].skindepth_show
#            self.view.gpr.compensateExtinction(k0,A)
#            self.view.update(self.view.gpr)
                
#            for n in range(traces):
#                trace = self.view.gpr.data[:,n]
#                max[n,0] = trace[refndxmin:refndxmax].max()
#                refndx[n,0] = where(trace[refndxmin:refndxmax]==trace[refndxmin:refndxmax].max())[0][-1] + refndxmin
#                sd = max[n,0]+10*log10(exp(-1))
#                skindx[n,0] = where(trace>sd)[0][-1]
##                skintime = (skindx[n,0]+topcut)*self.view.gpr.deltaT*1e9
#                skindepth[n,0] = self.view.gpr.t[skindx[n,0]] # in ns
#                refdepth[n,0] = self.view.gpr.t[refndx[n,0]] # in ns
#
#            self.view.pickdata.set_data("refy", refdepth.reshape((refdepth.size,)))
#            self.view.pickdata.set_data("refx", self.view.gpr.tracendx.reshape((self.view.gpr.tracendx.size,)))
#            self.view.pickdata.set_data("sky", skindepth.reshape((skindepth.size,)))
#            self.view.pickdata.set_data("skx", self.view.gpr.tracendx.reshape((self.view.gpr.tracendx.size,)))           
#            ui_info.ui.context["object"].skindepth_show = not ui_info.ui.context["object"].skindepth_show
    
    ### Proc Menu
    def static_correction(self, ui_info):
        self.view.gpr.staticCorrection(50)
        self.view.update(self.view.gpr)    
        
    ### Tool Menu
    def activate_picktool(self, ui_info):
        self.view.picktool.enable()
        
    def activate_traceselecttool(self, ui_info):
        self.view.traceselecttool.enable()
        
    def activate_zoomtool(self, ui_info):
        self.view.zoomtool.enable()
        
     
#    def activate_traceselecttool(self, ui_info):
#        self.view.traceselecttool = RangeSelection(component=self.view.cmapplot,
##                                                   left_button_selects=False,
##                                                   constrain=True,
##                                                   constrain_direction="x"
#                                                   )
#        self.view.cmapplot.tools.append(self.view.traceselecttool)
#        self.view.traceselectoverlay = RangeSelectionOverlay(component=self.view.cmapplot, axis="value",)
#        self.view.cmapplot.overlays.append(self.view.traceselectoverlay)  
        
                

class ProfileView(HasTraits):
    
    gpr = Instance(HUBRA)
    view = Instance(PlotUI)
    statustxt = Str
    file = Str
    #------------------------------------------------------------------------------
    #  File Menu:
    #------------------------------------------------------------------------------
    new_action = Action(name="&New", accelerator="Ctrl+N", action="new_file",
        tooltip="New (Ctrl+N)", image=r"../src/resources/icons/filenew-32.png")
    open_action = Action(name="&Open", accelerator="Ctrl+O", action="open_file",
        tooltip="Open (Ctrl+O)", image=r"../src/resources/icons/fileopen-32.png")
    save_action = Action(name="&Save",# accelerator="Ctrl+S",
        action="save", tooltip="Save (Ctrl+S)", image=r"../src/resources/icons/filesave-32.png")
    save_as_action = Action(name="Save &As", accelerator="Ctrl+Shift+S",
        action="save_as", tooltip="Save As (Ctrl+Shift+S)",
        image=r"../src/resources/icons/filesaveas-32.png")
    # Action to revert all changes.
    revert_action = Action(name="Revert", action="_on_revert",
        defined_when="ui.history is not None", enabled_when="ui.history.can_undo")
    # Action to close the view window.
    close_action = Action(name="E&xit", accelerator="Alt+X", action="_on_close",
        tooltip="Exit (Alt+X)", image=r"../src/resources/icons/fileclose-32.png")
    
    file_menu = Menu(open_action,
                     save_action,
                     close_action,
#                     CloseAction,
                     name="File")
    
    #------------------------------------------------------------------------------
    #  Edit Menu:
    #------------------------------------------------------------------------------
    # Action to undo last change.
    undo_action = Action(name="Undo", action="_on_undo", accelerator="Ctrl+Z",
        defined_when="ui.history is not None", enabled_when="ui.history.can_undo",
    #    image=ImageResource("undo"),
        tooltip="Undo (Ctrl+Z)")
    # Action to redo last undo.
    redo_action = Action(name="Redo", action="_on_redo", accelerator="Ctrl+Y",
        defined_when="ui.history is not None", enabled_when="ui.history.can_redo",
    #    image=ImageResource("redo.png"),
        tooltip="Redo (Ctrl+Y)")
    # Action to edit plot options
    plot_action = Action(name="Edit Plot ...", action="edit_plot", accelerator="Ctrl+E",
                         tooltip="Edit plot options (Ctrl+E)",
                         image=r"../src/resources/icons/edit-32.png")
    
    options_action = Action(name="Prefere&nces", action="godot_options")
    
    edit_menu = Menu(undo_action,
                     redo_action,
                     plot_action,
                     name="Edit")
    
    #------------------------------------------------------------------------------
    #  View Menu:
    #------------------------------------------------------------------------------
    zoomtool_action = Action(name="Zoom", action="activate_zoomtool",
                             image=r"../src/resources/icons/viewmag+-32.png")
    
    metadata_action = Action(name="Meta Data", action="show_metadata")
    
    trackplot_action = Action(name="Track Plot", action="show_trackplot")
    traceplot_action = Action(name="Trace Plot", action="show_traceplot", accelerator="Ctrl+A")
    decayplot_action = Action(name="Decay Plot", action="show_decayplot", accelerator="Ctrl+B")
    reflectivityplot_action  =Action(name="Reflectivity Plot", action="show_reflectivityplot")
    
    skindepth_show = False
    skindepth_action = Action(name="Skin Depth", accelerator="Ctrl+D",
                              action="show_skindepth", tooltip="",
                              style="toggle", checked=skindepth_show)
    
    view_menu = Menu(zoomtool_action, "_",
                     metadata_action,
                     trackplot_action,
                     traceplot_action,
                     decayplot_action,
                     reflectivityplot_action,
                     skindepth_action,
                     name="View")
    
    #===========================================================================
    # Processing Menu:
    #===========================================================================
    static_correction_action = Action(name="Static Correction", action="static_correction")
    
    proc_menu = Menu(static_correction_action,
                     name="Processing")
        
    #------------------------------------------------------------------------------
    #  Tool Menu:
    #------------------------------------------------------------------------------
    picktool_action = Action(name="Pick Tool", action="activate_picktool",
                             accelerator="Ctrl+P",
                             image=r"../src/resources/icons/lin_agt_wrench-32.png")
    traceselect_action = Action(name="Trace Select Tool", action="activate_traceselecttool")
    
    
    
    tool_menu = Menu(picktool_action,
                     traceselect_action,
                     name="Tools")
    
    # Make a tool bar with the most common methods
    toolbar = ToolBar(
            "|", CloseAction, open_action, "_",plot_action,
            show_tool_names=False#, show_divider=False
            )
    
    
#    statusbar = StatusItem(width=200)
    
    # Main View
    traits_view = View(VGroup(
                              Item('@view', show_label=False),
                              Item('statustxt', show_label=False, style='readonly')
                              ),
                       menubar=MenuBar(file_menu,
                                       edit_menu,     
                                       view_menu,
                                       proc_menu,  
                                       tool_menu), 
#                       statusbar=statusbar,
#                       toolbar=toolbar,                
                       handler=Controller(),
                       title = "GPR Viewer",
                       resizable=True)
    
    @on_trait_change('view')
    def update_view(self):
        if self.gpr is not None and self.view is not None:
            self.view.update(self.gpr)
            self.view.picktool.data = self.view.gpr
        


def show_plot(file="", wdir=os.getcwd()):
    HomeDir = os.getcwd()
    ConfigFile = os.path.join(HomeDir,"resources/default.cfg")
    config = ConfigParser.SafeConfigParser()
    config.read(ConfigFile)
    
    wdir = config.get('startup', 'data_dir')
    file = config.get('startup', 'data_file')
    
    try:
        os.chdir(wdir)
    except OSError:
        wdir = os.getcwd()
        file = ""
        
    st = StartViewerTool(file, wdir)
    st.configure_traits()
    os.chdir(st.dir)
    
    gpr = HUBRA()
    gpr.readH5(st.file, st.trace_min, st.trace_max, st.sample_min, st.sample_max)
#    gpr.readH5(st.file, tracemin=0, tracemax=415, samplemin=145, samplemax=5100)
#    gpr.set_cmed(0.18)
    spt = StartProcessingTool()
    spt.configure_traits()
#    gpr.gatefreq = 1523123.
    if spt.stack:
        gpr.stackTraces(spt.stack_no)
#    gpr.subtractMean(150)
    if spt.remove_gating:
        gpr.removeGating()
#    gpr.backgroundRemoval()
#    gpr.equalizeTraces()
    if spt.linear_gain:
        gpr.linearGain(spt.lin_gain_val)
    if spt.compensate_spreading:
#        gpr.compensateSpread(a=0.0)
#        gpr.compensateVolSpreadDavis()
        gpr.compensateVivaldi()
#    gpr.powerDecay()
    if spt.normalize:
        gpr.normalize()
#    gpr.compensateExtinction(0.0118, 0.0003)
    if spt.decibel:
        gpr.lin2dB()
#    gpr.dBnormalize()
    if spt.correct_topography:
        gpr.correctTopography()
    
    view = PlotUI()
    profileview = ProfileView(gpr=gpr, view=view, file=st.file)
    if gpr.hascoords:
        profileview.statustxt="File: %s, Total Distance: %8.2f m" % (st.file, gpr.coords.total_distance)
    else:
        profileview.statustxt = "File: %s, Total Distance: N/A" % (st.file)
    profileview.configure_traits()

def main(argv=None):
#    show_plot()
#    show_plot("NUS07-5-7_1.h5", r"Y:\Data2007_08\CBAND\processed\NUS07-5-7_ps")
#    show_plot('20090204_stk25_1000ns.h5', r'Y:\Data2008_09\Hubra_proc\IPY')
#    show_plot('data0.h5', r'Y:\Data2008_09\Wisdom\1101_side traverse_lake B')
#    show_plot('data52_stk25.h5', r'Y:\Hubra_Svalbard\Holtedahlfonna_2009')
#    show_plot('20090215_data1_stk25_1000ns.h5', r'd:\users\karstm\My Documents\Python\processgpr\testdata')
    show_plot('KV08_stake4_stk25.h5', r'Y:\Hubra_Svalbard\Kongsvegen_2008')   
#    show_plot('data345.h5', r'Y:\fimbuldata\HUBRAdata\091120') 
#    show_plot('data345.h5', r'/mn/terra/hubradata/fimbuldata/HUBRAdata/091120') 
    
if __name__ == "__main__":
    sys.exit(main())
